<?php
namespace Tbf\Component\BarCode;
use Image_Barcode2;
use Symfony\Component\Yaml\Yaml;
use Tbf\Bundle\UploadBundle\FileBlob;
use Tbf\Bundle\UploadBundle\MemoryBlob;
use Tbf\Component\FileSystem\FileSystemFunction;
use Tbf\Component\Image\ImageFunction;

class BarCodeFunction {
    public static function newRequest(){
        return new BarCodeRequest();
    }
    public static function draw(BarCodeRequest $request){
        if ($request->getType()===BarCodeRequest::BARCODE_QR){
            return self::handleQr($request);
        }
        return self::handleLinear($request);
    }

    /**
     *
     * @param BarCodeRequest $request
     * @throws \Exception
     */
    protected static function handleQr(BarCodeRequest $request){
        if ($request->getImgType()!==BarCodeRequest::IMAGE_PNG){
            throw new \Exception('not implment output image type other than png in qr code');
        }
        if ($request->getOutputType()!==BarCodeRequest::OUTPUT_TYPE_FILE){
            $save_file_path = FileSystemFunction::getTmpFilePath($request->getImgType());
        }else{
            $save_file_path = $request->getSaveFilePath();
        }
        $enc = \QRencode::factory($request->getQrEclevel(),
            $request->getQrSize(),
            $request->getQrMargin());
        $enc->encodePNG($request->getText(),
            $save_file_path, false);

        return self::handleOutputTypeFromFile($save_file_path,$request->getOutputType(),$request->getImgType());
    }

    /**
     * @param BarCodeRequest $request
     */
    protected static function handleLinear(BarCodeRequest $request){
        if ($request->getImgType()!==BarCodeRequest::IMAGE_PNG){
            throw new \Exception('not implment output image type other than png with linear barcode');
        }
        if ($request->getOutputType()!==BarCodeRequest::OUTPUT_TYPE_FILE){
            $save_file_path = FileSystemFunction::getTmpFilePath($request->getImgType());
        }else{
            $save_file_path = $request->getSaveFilePath();
        }
        $img = Image_Barcode2::draw($request->getText(),
            $request->getType(),
            $request->getImgType(),
            false,
            $request->getLinearHeight(),
            $request->getLinearWidth(),
            $request->getLinearShowText(),
            $request->getLinearRotate()
        );
        if ($request->getOutputType()===BarCodeRequest::OUTPUT_TYPE_GD_IMAGE){
            return $img;
        }
        imagepng($img,$save_file_path);

        return self::handleOutputTypeFromFile($save_file_path,$request->getOutputType(),$request->getImgType());
    }

    /**
     * @param $save_file_path
     * @param $output_type
     * @param $img_type
     * @return null|MemoryBlob
     * @throws \Exception
     */
    protected static function handleOutputTypeFromFile($save_file_path,$output_type,$img_type){
        if ($output_type===BarCodeRequest::OUTPUT_TYPE_MEMORY_BLOB){
            $obj = MemoryBlob::fromFile($save_file_path,$img_type);
            FileSystemFunction::delete($save_file_path);
            return $obj;
        }
        if ($output_type===BarCodeRequest::OUTPUT_TYPE_ECHO){
            echo file_get_contents($save_file_path);
            FileSystemFunction::delete($save_file_path);
            return null;
        }
        if ($output_type===BarCodeRequest::OUTPUT_TYPE_STRING){
            $string = file_get_contents($save_file_path);
            FileSystemFunction::delete($save_file_path);
            return $string;
        }
        //TODO image 类型问题
        if ($output_type===BarCodeRequest::OUTPUT_TYPE_GD_IMAGE){
            $image = imagecreatefrompng($save_file_path);
            FileSystemFunction::delete($save_file_path);
            return $image;
        }
        if ($output_type!==BarCodeRequest::OUTPUT_TYPE_FILE){
            throw new \Exception('invalid output image type: %s',$output_type);
        }
    }

    public static function getTestImageResponse(){
        return ImageFunction::wideImageToResponse(BarCodeFunction::getTestImage());
    }

    /**
     * 视觉测试barcode
     * @return \WideImage_TrueColorImage
     */
    public static function getTestImage(){
        $data = array(
            array('type'=>BarCodeRequest::BARCODE_CODE39,'text'=>'123456'),
            array('type'=>BarCodeRequest::BARCODE_EAN13,'text'=>'1234567890123'),
            array('type'=>BarCodeRequest::BARCODE_INT25,'text'=>'123456'),
            array('type'=>BarCodeRequest::BARCODE_EAN8,'text'=>'12345678'),
            array('type'=>BarCodeRequest::BARCODE_POSTNET,'text'=>'123456'),
            array('type'=>BarCodeRequest::BARCODE_UPCA,'text'=>'123456789012'),
            array('type'=>BarCodeRequest::BARCODE_UPCE,'text'=>'12345678'),
            array('type'=>BarCodeRequest::BARCODE_CODE128,'text'=>'123456','linear_show_text'=>false,'below'=>'show_text=false'),
            array('type'=>BarCodeRequest::BARCODE_CODE128,'text'=>'123456','linear_width'=>1,'below'=>'width=1'),
            array('type'=>BarCodeRequest::BARCODE_CODE128,'text'=>'123456','linear_width'=>2,'below'=>'width=2'),
            array('type'=>BarCodeRequest::BARCODE_CODE128,'text'=>'123456','linear_width'=>3,'below'=>'width=3'),

            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'123456'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>"http://www.google.com/".str_repeat("\n12345678901234567890",20)),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>"http://www.google.com/".str_repeat("\n12345678901234567890",40)),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>"http://www.google.com/".str_repeat("\n12345678901234567890",80),'qr_size'=>1,'below'=>'size=1'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>1,'below'=>'size=1'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>2,'below'=>'size=2'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>3,'below'=>'size=3'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>4,'below'=>'size=4'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>5,'below'=>'size=5'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>6,'below'=>'size=6'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>7,'below'=>'size=7'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>8,'below'=>'size=8'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>9,'below'=>'size=9'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_size'=>10,'below'=>'size=10'),

            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_eclevel'=>BarCodeRequest::QR_ECLEVEL_L,'below'=>'eclevel=L'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_eclevel'=>BarCodeRequest::QR_ECLEVEL_M,'below'=>'eclevel=M'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_eclevel'=>BarCodeRequest::QR_ECLEVEL_Q,'below'=>'eclevel=Q'),
            array('type'=>BarCodeRequest::BARCODE_QR,'text'=>'1234567890123456789','qr_eclevel'=>BarCodeRequest::QR_ECLEVEL_H,'below'=>'eclevel=H'),
        );
        /** @var \WideImage_Image[] $image_list */
        $image_list = array();
        $total_height = 0;
        $space = 28;
        $max_width = 0;
        foreach($data as $case){
            $req = BarCodeFunction::newRequest()
                ->setOutputGdImage()
                ->setType($case['type'])
                ->setText($case['text']);
            if (!empty($case['linear_width'])){
                $req->setLinearWidth($case['linear_width']);
            }
            if (isset($case['linear_show_text'])){
                $req->setLinearShowText($case['linear_show_text']);
            }
            if (!empty($case['qr_size'])){
                $req->setQrSize($case['qr_size']);
            }
            if (!empty($case['qr_eclevel'])){
                $req->setQrEclevel($case['qr_eclevel']);
            }
            $img = $req->draw();
            $img = \WideImage::loadFromHandle($img);
            $image_list[] = $img;
            $below_text = $case['type'].'-'.$case['text'];
            if (!empty($case['below'])){
                $below_text .= '-'.$case['below'];
            }
            $image_list[] = ImageFunction::newFontDraw()->setText($below_text)->toWideImage();
        }
        foreach($image_list as $this_image){
            $total_height += $this_image->getHeight() + $space;
            if ($max_width<$this_image->getWidth()){
                $max_width = $this_image->getWidth();
            }
        }
        $image = \WideImage::createPaletteImage($max_width+20,$total_height);
        $image->fill(0,0,$image->allocateColor(200,200,200));
        //$image->fill(0,0,$image->allocateColor(255,255,255));
        $y = 0;
        foreach($image_list as $this_image){
            $this_image->copyTo($image,10,$y);
            $y += $this_image->getHeight() + $space;
        }
        return $image;
    }
}